{
   Copyright 2005 Log4Delphi Project

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
}
{*----------------------------------------------------------------------------
   Contains the TProperties class.
   @version 0.2
   @author <a href="mailto:tcmiller@users.sourceforge.net">Trevor Miller</a>
  ----------------------------------------------------------------------------}
unit RclProperties;

interface

uses
   Classes, RclString, RclPrintWriter, Dialogs, SysUtils;

type
   TProperties = class (TObject)
   protected
      FValues : TStrings;
      function StartsStr(const APrefix : String; const ASource : String) : Boolean;
   public
      constructor Create;
      destructor Destroy; Override;
      procedure SetProperty(const AKey, AValue : String);
      procedure RemoveProperty(const AKey : String);
      procedure Save(AStream : TStream);
      procedure Load(AStream : TStream);
      procedure Clear();
      function GetProperty(const AKey : String): String; overload; virtual;
      function GetProperty(const AKey, ADefaultValue : String): String; overload;
          virtual;
      function GetPropertyNames() : TStrings;
      function Subset(const APrefix : String) : TProperties;
   end;

implementation

function TProperties.StartsStr(const APrefix : String; const ASource : String)
   : Boolean;
begin
   StartsStr := (CompareStr(APrefix, Copy(ASource, 0, Length(APrefix))) = 0);
end;

constructor TProperties.Create;
begin
   inherited Create;
   FValues := TStringList.Create;
end;

destructor TProperties.Destroy;
begin
   clear();
   FValues.Free;
   inherited Destroy;
end;

procedure TProperties.SetProperty(const AKey, AValue : String);
var
   index : Integer;
begin
   index := FValues.IndexOf(AKey);
   if (index < 0) then begin
      FValues.AddObject(AKey, TString.Create(AValue));
   end else begin
      TString(FValues.Objects[index]).setString(AValue);
   end;
end;

procedure TProperties.RemoveProperty(const AKey : String);
var
   index : Integer;
begin
   index := FValues.IndexOf(AKey);
   if (index >= 0) then begin
      FValues.Objects[index].Free;
      FValues.Delete(index);
   end;
end;

procedure TProperties.Save(AStream : TStream);
var
   writer : TPrintWriter;
   index : Integer;
begin
   writer := TPrintWRiter.Create(AStream);
   for index := 0 to FValues.Count-1 do begin
      writer.print(FValues[index]);
      writer.print('=');
      writer.println(TString(FValues.Objects[index]).toString);
   end;
   writer.Free;
end;

procedure TProperties.Load(AStream : TStream);
var
   strings : TStrings;
   count : Integer;
   index : Integer;
begin
   clear();
   strings := TStringList.Create;
   strings.LoadFromStream(AStream);
   for count := 0 to strings.Count-1 do begin
      if (Length(strings[count]) > 0) then
         if (strings[count][1] <> '#') then begin
            index := Pos('=', strings[count]);
            if (index >= 0) then begin
               FValues.AddObject(trim(copy(strings[count],0,index-1)),
                  TString.Create(trim(copy(strings[count],index+1,
                  Length(strings[count])-index))));
            end;
         end;
   end;
   strings.Free;
end;

procedure TProperties.Clear();
var
   count : Integer;
begin
   for count := 0 to FValues.Count-1 do
      FValues.Objects[count].Free;
   FValues.Clear;
end;

function TProperties.GetProperty(const AKey : String): String;
begin
   result := getProperty(Akey, '');
end;

function TProperties.GetProperty(const AKey, ADefaultValue : String): String;
var
   index : Integer;
begin
   index := FValues.IndexOf(AKey);
   if (index >= 0) then
      result := TString(FValues.Objects[index]).toString
   else
      result := ADefaultValue;
end;

function TProperties.GetPropertyNames() : TStrings;
var
   tmp : TStrings;
begin
   tmp := TStringList.Create;
   tmp.Text := FValues.Text;
   result := tmp;
end;

function TProperties.Subset(const APrefix : String) : TProperties;
var
   tmp : TProperties;
   i : Integer;
begin
   tmp := TProperties.Create;
   for i := 0 to FValues.Count-1 do
      if (StartsStr(APrefix, FValues[i])) then
         tmp.FValues.AddObject(FValues[i], TString.Create(TString(FValues.Objects[i])));
   result := tmp;
end;

end.
 